package edu.biwu.utils;

import edu.biwu.dao.ProductDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author 王俊彪
 * @version 1.0
 */
@Component
public class TransactionProxyFactory {
    @Autowired
    TransactionManager transactionManager;
    @Autowired
    ApplicationContext applicationContext;

    public Object createProxyInstance(Class cls){
        if (cls.getInterfaces().length!=0){
            return Proxy.newProxyInstance(cls.getClassLoader(),
                    cls.getInterfaces(),
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            Object retval= null;

                            if (!method.getName().startsWith("find")){
                                try {
                                    transactionManager.beginTransaction();

                                    retval = method.invoke(applicationContext.getBean(cls),args);

                                    transactionManager.commit();
                                } catch (Exception e) {
                                    transactionManager.rollBack();
                                    throw new RuntimeException(e);
                                }finally {
                                    transactionManager.release();
                                }
                            }
                            return retval;
                        }
                    });
        }else {
            Enhancer enhancer = new Enhancer();
            //设置代理类的父类
            enhancer.setSuperclass(cls);
            //设置回调函数
            enhancer.setCallback(new MethodInterceptor() {
                @Override
                public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                    Object retval= null;

                    if (!method.getName().startsWith("find")){
                        try {
                            transactionManager.beginTransaction();

                            retval = method.invoke(applicationContext.getBean(cls),args);

                            transactionManager.commit();
                        } catch (Exception e) {
                            transactionManager.rollBack();
                            throw new RuntimeException(e);
                        }finally {
                            transactionManager.release();
                        }
                    }
                    return retval;
                }
            });
            //返回代理对象
            return enhancer.create();
        }
    }
}